/*
 * Copyright 2010 WithOne Co. Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.co.withone.osgi.gadget.pictureviewer.impl;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * PictureViewerMainView class provide main view.
 * 
 * @author funakky
 */
public class PictureViewerMainView extends JFrame {

	private volatile byte[] picture;

	/**
	 * Create new main view.
	 */
	public PictureViewerMainView() {
		super("PictureViewer");
		initComponents();
	}

	private void initComponents() {
		final JFrame frame = this;
		this.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				switch (e.getKeyCode()) {
				case KeyEvent.VK_F:
					GraphicsEnvironment env = GraphicsEnvironment
							.getLocalGraphicsEnvironment();
					GraphicsDevice device = env.getDefaultScreenDevice();
					device.setFullScreenWindow(frame);
					break;

				case KeyEvent.VK_ESCAPE:
					env = GraphicsEnvironment.getLocalGraphicsEnvironment();
					device = env.getDefaultScreenDevice();
					device.setFullScreenWindow(null);
					break;

				case KeyEvent.VK_W:
					frame.dispose();
					frame.setUndecorated(!frame.isUndecorated());
					frame.setVisible(true);
					break;

				case KeyEvent.VK_C:
					frame.setBounds(frame.getX(), frame.getY(), 160, 120);
					break;

				default:
					break;
				}
			}
		});
		this.setContentPane(new PictureViewPanel());
		this.setBackground(Color.BLACK);
		this.setBounds(0, 0, 160, 120);
		this.dispose();
		this.setUndecorated(true);
	}

	/**
	 * Set picture.
	 * 
	 * @param picture
	 *            picture for view
	 */
	public void setPicture(byte[] picture) {
		this.picture = picture;
	}

	private class PictureViewPanel extends JPanel {

		@Override
		public void paintComponent(Graphics g) {
			final byte[] pic = picture;
			if (pic == null) {
				return;
			}

			final Graphics2D g2 = (Graphics2D) g;

			try {
				final InputStream is = new ByteArrayInputStream(pic);
				final BufferedImage readImage = ImageIO.read(is);
				if (readImage == null) {
					return;
				}

				final int panelWidth = this.getWidth();
				final int panelHeight = this.getHeight();

				final int imageWidth = readImage.getWidth();
				final int imageHeight = readImage.getHeight();

				final double widthScale = ((double) panelWidth) / imageWidth;
				final double heightScale = ((double) panelHeight) / imageHeight;

				final double scale;
				final int paintStartX;
				final int paintStartY;
				if (widthScale > heightScale) {
					scale = heightScale;
					paintStartX = (int) ((panelWidth - imageWidth * scale) / 2);
					paintStartY = 0;
				} else {
					scale = widthScale;
					paintStartX = 0;
					paintStartY = (int) ((panelHeight - imageHeight * scale) / 2);
				}

				final int scaledImageWidth = (int) (imageWidth * scale);
				final int scaledImageHeight = (int) (imageHeight * scale);

				AffineTransformOp op = new AffineTransformOp(AffineTransform
						.getScaleInstance(scale, scale), null);
				BufferedImage destImage = new BufferedImage(scaledImageWidth,
						scaledImageHeight, readImage.getType());
				op.filter(readImage, destImage);

				g2.drawImage(destImage, paintStartX, paintStartY, this);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
